package com.longrise.android.util;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Enumeration;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import java.util.zip.ZipOutputStream;

import android.os.Environment;

/**
 * 文件夹压缩 ZipUtil.zip(Environment.getExternalStorageDirectory()+"/Download",
 * Environment.getExternalStorageDirectory()+"/Download.zip");
 * 
 * @author Administrator
 * 
 */
public class ZipUtil 
{

	/**
	 * zip压缩文件或目录
	 * @param srcfile：源文件或目录
	 * @param outZipFile：zip文件输出
	 * @return
	 */
	public static boolean zipDirOrFile(File srcfile, File outZipFile) 
	{
		ZipOutputStream out = null;
		File[] entries = null;
		try
		{
			if(null==srcfile)return false;
			if(null==outZipFile)return false;
			if(!srcfile.exists()) return false;
			out = new ZipOutputStream(new FileOutputStream(outZipFile));
			if(null!=out)
			{
				if(srcfile.isFile()) 
				{
					zipFileOrDirectory(out, srcfile, "");
				}
				else
				{				
					entries = srcfile.listFiles();
					if(null!=entries)
					{
						for (int i = 0; i < entries.length; i++) 
						{						
							zipFileOrDirectory(out, entries[i], "");
						}
					}
				}
				return true;
			}
		}
		catch(Exception ex){}
		finally
		{
			if(null!=out) 
			{
				try 
				{
					out.close();
				}
				catch (IOException ex) 
				{
				}
			}
			out = null;
			srcfile = null;
			outZipFile = null;
			entries = null;
		}
		return false;
	}
	/**
	 * zip压缩文件或目录
	 * @param srcDirOrFilePath：源文件或目录路径
	 * @param outZipFilePath：zip文件输出路径
	 * @return
	 */
	public static boolean zipDirOrFile(String srcDirOrFilePath, String outZipFilePath) 
	{
		File outFile = null;
		File fileOrDirectory = null;
		try 
		{
			if(null==srcDirOrFilePath || "".equals(srcDirOrFilePath))return false;
			if(null==outZipFilePath || "".equals(outZipFilePath))return false;
			
			outFile = new File(outZipFilePath);
			if(null!=outFile)
			{				
				fileOrDirectory = new File(srcDirOrFilePath);
				if(null!=fileOrDirectory)
				{
					return zipDirOrFile(fileOrDirectory,outFile);
				}
			}
		} 
		catch (Exception ex) 
		{
		}
		finally
		{
			outFile = null;
			fileOrDirectory = null;
			srcDirOrFilePath = null;
			outZipFilePath = null;
		}
		return false;
	}

	private static void zipFileOrDirectory(ZipOutputStream out,	File fileOrDirectory, String curPath) {
		
		FileInputStream in = null;
		byte[] buffer = null;
		int bytes_read;
		ZipEntry entry = null;
		try 
		{
			if(null==out || null==fileOrDirectory)return;
			if (!fileOrDirectory.isDirectory()) 
			{		
				buffer = new byte[4096];
				if(null!=buffer)
				{
					in = new FileInputStream(fileOrDirectory);
					if(null!=in)
					{
						entry = new ZipEntry(curPath + fileOrDirectory.getName());
						if(null!=entry)
						{
							out.putNextEntry(entry);
							while ((bytes_read = in.read(buffer)) != -1) 
							{
								out.write(buffer, 0, bytes_read);
							}
							out.closeEntry();
						}
					}
				}
			}
			else
			{			
				File[] entries = fileOrDirectory.listFiles();
				for (int i = 0; i < entries.length; i++) 
				{
					zipFileOrDirectory(out, entries[i], curPath	+ fileOrDirectory.getName() + "/");
				}
			}
		}
		catch (IOException ex)
		{
		}
		finally 
		{
			if(in != null) 
			{
				try 
				{
					in.close();
				}
				catch (IOException ex) 
				{
				}
			}
			buffer = null;
			entry = null;
			out = null;
			fileOrDirectory = null;
			curPath = null;
		}
	}

	public static boolean unZipFile(File zipFilePath, File outputDirPath)
	{
		ZipFile zipFile = null;
		Enumeration<?> enumeration = null;
		ZipEntry zipEntry = null;
		String entryName = null;
		InputStream in = null;
		FileOutputStream out = null;
		String name = null;
		try
		{
			if(null==zipFilePath || null==outputDirPath)return false;
			if(outputDirPath.exists())
			{
				outputDirPath.delete();
			}
			outputDirPath.mkdir();
			zipFile = new ZipFile(zipFilePath);
			if(null!=zipFile)
			{
				enumeration = zipFile.entries();
				if(null!=enumeration)
				{
					while (enumeration.hasMoreElements()) 
					{
						zipEntry = (ZipEntry) enumeration.nextElement();
						if(null!=zipEntry)
						{
							entryName = zipEntry.getName();
							if(null!=entryName)
							{
								try 
								{
									if (zipEntry.isDirectory()) 
									{
										name = zipEntry.getName();
										if(null!=name && !"".equals(name))
										{
											name = name.substring(0, name.length() - 1);		
											File f = new File(outputDirPath ,name);
											f.mkdirs();
										}
									} 
									else
									{
										int index = entryName.lastIndexOf("\\");
										if (index != -1) 
										{
											File df = new File(outputDirPath , entryName.substring(0, index));
											df.mkdirs();
										}
										index = entryName.lastIndexOf("/");
										if (index != -1) 
										{
											File df = new File(outputDirPath, entryName.substring(0, index));
											df.mkdirs();
										}
										File f = new File(outputDirPath, zipEntry.getName());
										// f.createNewFile();
										in = zipFile.getInputStream(zipEntry);
										out = new FileOutputStream(f);
		
										int c;
										byte[] by = new byte[1024];
		
										while ((c = in.read(by)) != -1) 
										{
											out.write(by, 0, c);
										}
										out.flush();
									}
								}
								catch (IOException ex) 
								{							
								}
								finally 
								{
									if(in != null) 
									{
										try 
										{
											in.close();
										}
										catch (IOException ex) 
										{
										}
									}
									if (out != null) 
									{
										try
										{
											out.close();
										}
										catch (IOException ex) 
										{
										}
									}
								}
							}
						}
					}
				}
			}
			return true;
		}
		catch(Exception ex){}
		finally
		{
			zipFile = null;
			enumeration = null;
			zipEntry = null;
			entryName = null;
			in = null;
			out = null;
		}
		return false;
	}
	public static boolean unZipFile(String zipFilePath, String outputDirPath)
	{
		File zipFile = null;
		File outFile = null;
		try 
		{
			if(null==zipFilePath || "".equals(zipFilePath))return false;
			if(null==outputDirPath || "".equals(outputDirPath))return false;
			zipFile = new File(zipFilePath);
			outFile = new File(outputDirPath);
			if(null!=zipFile && null!=outFile)
			{
				if(zipFile.exists())
				{
					return unZipFile(zipFile,outFile);
				}
			}
		}
		catch (Exception ex) 
		{
			
		} 
		finally 
		{
			zipFile = null;
			outFile = null;
		}
		return false;
	}
	
	/**
	 * 字符串压缩
	 * @param str
	 * @return
	 * @throws IOException
	 */
	public static String compressString(String str)
	{
		try
		{
			if (str == null || str.length() == 0) 
			{
				return str;
			}			
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			GZIPOutputStream gzip = new GZIPOutputStream(out);
			gzip.write(str.getBytes());
			gzip.close();
			return out.toString("ISO-8859-1");
		}
		catch(Exception ex){}
		finally
		{			
		}
		return null;
	}

	/**
	 * 字符串解压缩
	 * @param str
	 * @return
	 * @throws IOException
	 */
	public static String unCompressString(String str) 
	{
		try
		{
			if(str == null || str.length() == 0) 
			{
				return str;
			}
			ByteArrayOutputStream out = new ByteArrayOutputStream();
			ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes("ISO-8859-1"));
			GZIPInputStream gunzip = new GZIPInputStream(in);
			byte[] buffer = new byte[256];
			int n;
			while ((n = gunzip.read(buffer)) >= 0) 
			{
				out.write(buffer, 0, n);
			}
			// toString()使用平台默认编码，也可以显式的指定如toString("GBK")
			return out.toString();
		}
		catch(Exception ex){}
		finally
		{			
		}
		return null;
	}
	
}
